package com.jianqiao.delivery.delivery.service.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jianqiao.delivery.delivery.service.ResolveAddressService;
import com.jianqiao.delivery.expresscity.entity.CityEntity;
import com.jianqiao.delivery.expresscity.entity.DistrictEntity;
import com.jianqiao.delivery.expresscity.entity.ProvinceEntity;
import com.jianqiao.delivery.expresscity.entity.StreetEntity;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.IntStream;

/**
 * author: cyx
 * create: 2024/11/28 10:33
 **/
@Service
public class ResolveAddressServiceImpl implements ResolveAddressService {

    // 正则表达式: 匹配日本电话号码（包括可能的 -）
    private static final String PHONE_REGEX = "\\d{2,4}-?\\d{2,4}-?\\d{4}";

    // 姓名的简化假设：只允许包含假名或汉字，且不包含电话号码部分
    private static final String NAME_REGEX = ".*?([\\p{InCJKUnifiedIdeographs}]{2,})$";

    // 正则表达式：匹配并拆分地址
    private static final String SPLIT_ADDRESS_REGEX =
            "(?:(?<province>[^\\d]+(都|府|県)))" +    // 省（都道府县）
            "(?:(?<city>[^\\d]+(市|区|町|村)))" +    // 市（市区町村）
            "(?:(?<district>[^\\\\d]+(?:丁目|番地|号|街道)[^\\\\d\\w]*[0-9０-９ー-]*))" +  // 区/丁目部分，允许部分字符
            "(?:\\s*(?<building>[^\\d]+(?:ビル|館|タワー|フロア|階|ホテル)?[\\w\\p{IsHan}ーー]*))?";  // 大楼部分（可选）

    public Boolean checkFullProvince(String address) {
        if (address.equals("都") || address.equals("府") ||
            address.equals("道") || address.equals("県")) {
            return true;
        }
        return false;
    }

    /**
      *methood: 解析日本地址
      *auth: cyx
      *time: 2024/11/28 10:48
    **/
    @Override
    public AjaxResult resolveJpAddressService(String paramStr) throws IOException {
        paramStr = paramStr.replaceAll("\\s+" ,"");

        //读取日本省的JSON文件
        ObjectMapper objectMapper = new ObjectMapper();
        Map<String ,String> jpAddressMap = objectMapper.readValue(new File("D:\\项目\\物流-git\\wuliu\\ruoyi-admin\\src\\main\\resources\\jpaddress.json") ,Map.class);
        Set<String> jpAddressList = jpAddressMap.keySet();

        //先对地址的省份判断是否完整
        for (String s : jpAddressList) {
            String provinceName = s.substring(0, s.length() - 1);
            //有写省份
            if (paramStr.contains(provinceName)) {
                char charAt = paramStr.split(provinceName)[1].charAt(0);
                if (!checkFullProvince(String.valueOf(charAt))) {
                    paramStr = paramStr.replace(provinceName ,s);
                }
                break;
            }
        }

        Map<String, Object> result = new HashMap<>();

        // 先匹配电话号码
        Pattern phonePattern = Pattern.compile(PHONE_REGEX);
        Matcher phoneMatcher = phonePattern.matcher(paramStr);
        if (phoneMatcher.find()) {
            result.put("phone", phoneMatcher.group());
            paramStr = paramStr.replace(phoneMatcher.group(), "");
        }

        // 匹配地址
//        Pattern addressPattern = Pattern.compile(ADDRESS_REGEX);
//        Matcher addressMatcher = addressPattern.matcher(paramStr);
//        if (addressMatcher.find()) {
//            String address = addressMatcher.group();
//            result.put("address", address);
//            paramStr = paramStr.replace(addressMatcher.group(), "");
//            //查分地址
//            Map<String, String> addressMap = splitAddress(address);
//            result.put("addressMap" ,addressMap);
//        }

        //判断用户输入开头是姓名还是地址
        Integer index = jpAddressList.stream()
                .filter(paramStr::contains)
                .map(paramStr::indexOf)
                .findFirst()
                .orElse(-1);
        //如果姓名出现在地址之前
        if (index != 0) {
            //切分
            try {
                String nameStr = paramStr.substring(0, index);
                String address = paramStr.replace(nameStr, "");
                Map<String, String> addressMap = splitAddress(address);

                result.put("name" ,nameStr);
                result.put("address" ,address);
                result.put("addressMap" ,addressMap);
                result.put("zipCode" ,jpAddressMap.get(addressMap.get("province")));
            } catch (Exception e) {
                return AjaxResult.error("Have something wrong");
            }
        } else {
            //11.30
//            String regex = "^(.*?\\d{1,}[-丁目号\\s]*)\\s*([一-龯ぁ-んァ-ンー]+)\\s*(090\\d{8})$";
//            Pattern pattern = Pattern.compile(regex);
//            Matcher matcher = pattern.matcher(paramStr);
//
//            if (matcher.find()) {
//                String address = matcher.group(1).trim();
//                String name = matcher.group(2).trim();
//                String phone = matcher.group(3).trim();
//
//                System.out.println("地址: " + address);
//                System.out.println("姓名: " + name);
//                System.out.println("手机号码: " + phone);
//                System.out.println();
//            } else {
//                System.out.println("未匹配到内容: " + paramStr);
//            }


            //先提取出姓名   11.29方案
            String name = "";
            Pattern pattern = Pattern.compile(NAME_REGEX);
            Matcher matcher = pattern.matcher(paramStr);
            if (matcher.find()) {
                name = matcher.group(1);
                System.out.println(name);
                System.out.println(matcher.group());
            }

            result.put("name", name);
            paramStr = paramStr.replace(name ,"");
            result.put("address", paramStr);
            Map<String, String> addressMap = splitAddress(paramStr);
            String province = addressMap.get("province");
            for (String s : jpAddressList) {
                if (s.equals(province)) {
                    result.put("zipCode" ,jpAddressMap.get(s));
                    break;
                }
            }
            result.put("addressMap" ,addressMap);
        }

        if (result.isEmpty()) {
            return AjaxResult.error("Scan Error");
        }

        return AjaxResult.success(result);
    }

    public Map<String ,String> splitAddress(String address) {
        Map<String, String> result = new HashMap<>();

        // 编译正则表达式并匹配输入的地址
        Pattern addressPattern = Pattern.compile(SPLIT_ADDRESS_REGEX);
        Matcher addressMatcher = addressPattern.matcher(address);

        // 如果找到匹配的地址部分
        if (addressMatcher.find()) {
            result.put("province", addressMatcher.group("province"));
            result.put("city", addressMatcher.group("city"));
            result.put("district", addressMatcher.group("district"));
            result.put("v", "381");
            result.put("n", "日本");
            result.put("building", addressMatcher.group("building") != null ? addressMatcher.group("building") : "N/A");
        }

        return result;
    }

    /**===========================================印尼地区==========================================**/
    @Override
    public AjaxResult resolveIndAddressService(String param) throws IOException {
        param = param.toUpperCase();
        Map<String, String> indResultMap = new HashMap<>();
        Map<String, Object> result = new HashMap<>();
        //读取印尼地区的JSON文件
        ObjectMapper objectMapper = new ObjectMapper();
        List<ProvinceEntity> indAddressList = objectMapper.readValue(new File("D:\\项目\\物流-git\\wuliu\\ruoyi-admin\\src\\main\\resources\\indaddress_dev.json") ,List.class);
        //先把电话拆出来
        Pattern phonePattern = Pattern.compile("(\\+62|08|8)\\d{8,15}");
        Matcher phoneMatcher = phonePattern.matcher(param);
        if (phoneMatcher.find()) {
            String phoneNumber = phoneMatcher.group(0);
            result.put("phone" ,phoneNumber);
            param = param.replace(phoneNumber ,"");
        }

        //拆解地址
        String detailAddress = "";
        String[] splitParam = param.split("\\.");
        List<String> paramList = Arrays.asList(splitParam);
        Boolean findProvince = false;
        Integer nameIndex = -1;
        for (int i = paramList.size() - 1 ;i >= 0 ;i --) {
            String[] secondSplit = paramList.get(i).split(",");
            List<String> secondParamList = Arrays.asList(secondSplit);
            for (int j = secondParamList.size() - 1 ;j >= 0 ;j --) {
                if (findProvince) {
                    break;
                }
                String secondStr = secondParamList.get(j);
                for (Object o : indAddressList) {
                    ObjectMapper oMap = new ObjectMapper();
                    ProvinceEntity provinceEntity = oMap.convertValue(o, ProvinceEntity.class);
                    String provinceName = provinceEntity.getProvinceName();
                    if (secondStr.contains(provinceName)) {
                        provinceName = String.valueOf(provinceName.charAt(0)).toUpperCase() + provinceName.substring(1).toLowerCase();
                        indResultMap.put("province", provinceName);
                        indResultMap.put("country", "印度尼西亚");
                        indResultMap.put("n", "Indonesia");
                        findProvince = true;
                        break;
                    }
                }
            }
            //姓名在地址后
            if (!findProvince && i == paramList.size() - 1) {
                //可能是姓名
                result.put("name" ,paramList.get(i));
                nameIndex = 0;
            }
            //姓名在地址前
            else if (findProvince && i == 0 && StringUtils.isNull(result.get("name"))) {
                //可能是姓名
                result.put("name" ,paramList.get(i));
                nameIndex = 1;
            }
            if (findProvince && StringUtils.isNull(result.get("name"))) {
                detailAddress = paramList.get(i) + detailAddress;
            }
            if (findProvince && nameIndex == 0) {
                detailAddress = paramList.get(i) + detailAddress;
            }
//            if (findProvince && !StringUtils.isNull(result.get("name")) && nameIndex == 1) {
//                detailAddress = paramList.get(i) + detailAddress;
//            }
        }
        result.put("address" ,detailAddress);

        result.put("addressMap" ,indResultMap);
        Map<String ,String> indAddressZipMap = objectMapper.readValue(new File("D:\\项目\\物流-git\\wuliu\\ruoyi-admin\\src\\main\\resources\\indaddress.json") ,Map.class);
        Set<String> indAddressZipList = indAddressZipMap.keySet();
        String province = indResultMap.get("province");
        for (String s : indAddressZipList) {
            if (s.equals(province)) {
                result.put("zipCode" ,indAddressZipMap.get(s));
            }
        }
        return AjaxResult.success(result);
    }

    public Map<String ,String> parseAddress(String address) {
        // 地址拆解的正则表达式
        String streetRegex = "(?<=,\\s)([A-Za-z0-9\\s,]+)(?=,\\sJl\\.)";  // 匹配街道地址
        String subdistrictRegex = "(?<=,\\s)(Kota\\s[A-Za-z0-9\\s]+)(?=,\\s[\\w]+\\s[\\w]+)";  // 匹配子区
        String cityRegex = "(?<=,\\s)([A-Za-z\\s]+)(?=\\sIndonesia)";  // 匹配城市
        String provinceRegex = "(?<=,\\s)([A-Za-z\\s]+)(?=\\sIndonesia)";  // 匹配省
        String countryRegex = "(?<=\\s)(Indonesia)";  // 匹配国家

        // 用正则表达式匹配各个部分
        String street = extract(address, streetRegex);
        String subdistrict = extract(address, subdistrictRegex);
        String city = extract(address, cityRegex);
        String province = extract(address, provinceRegex);
        String country = extract(address, countryRegex);

        Map<String, String> resultMap = new HashMap<>();
        resultMap.put("country" ,country);
        resultMap.put("province" ,province);
        resultMap.put("city" ,city);
        resultMap.put("subdistrict" ,subdistrict);
        resultMap.put("street" ,street);

        return resultMap;
    }

    // 正则匹配
    private static String extract(String text, String regex) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(text);
        if (matcher.find()) {
            return matcher.group();
        }
        return null;
    }
}
